package com.jiangyao.common.utils;

import org.apache.commons.lang.StringUtils;

import java.util.Calendar;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <p>
 * 验证工具类
 * </p>
 *
 * @author yangyongchuan
 * @since 2020-05-08
 */
public class ValidateUtil {

	private final static Pattern P_MOBILE = Pattern.compile("^[1][0-9]{10}$");

	public static boolean isMobileNo(String mobiles) {
		if (StringUtils.isBlank(mobiles)) {
			return false;
		}
		return P_MOBILE.matcher(mobiles).matches();
	}

	private final static Pattern P_TIME_HM = Pattern.compile("^(([0-1]\\d)|(2[0-4])):[0-5]\\d$");

	/**
	 * 验证是否是 (时:分) 的格式
	 */
	public static boolean isHourminute(String time) {
		if (StringUtils.isBlank(time)) {
			return false;
		}
		return P_TIME_HM.matcher(time).matches();
	}

	private final static Pattern P_EMAIL = Pattern.compile("^([a-zA-Z0-9]*[-_]*[a-zA-Z0-9]+)*@([a-zA-Z0-9]*[-_]?[a-zA-Z0-9]+)+[\\.][A-Za-z]{2,3}([\\.][A-Za-z]{2})?$");

	public static boolean isEmail(String email) {
		if (StringUtils.isBlank(email)) {
			return false;
		}
		return P_EMAIL.matcher(email).matches();
	}

	private final static Pattern P_PHONE = Pattern.compile("^(([1][0-9]{10})|^((\\d{7,8})|(\\d{4}|\\d{3})-(\\d{7,8})|(\\d{4}|\\d{3})-(\\d{7,8})-(\\d{4}|\\d{3}|\\d{2}|\\d{1})|(\\d{7,8})-(\\d{4}|\\d{3}|\\d{2}|\\d{1}))$)$");

	public static boolean isPhoneNo(String phoneNo) {
		if (StringUtils.isBlank(phoneNo)) {
			return false;
		}
		return P_PHONE.matcher(phoneNo).matches();
	}

	/**
	 * 国际传真
	 */
	public static boolean isFaxNo(String faxNo) {
		if (StringUtils.isBlank(faxNo)) {
			return false;
		}
		return isPhoneNo(faxNo);
	}

	private final static Pattern P_ZIP_CODE = Pattern.compile("[0-9]{6}");

	public static boolean isZipCode(String zipCode) {
		if (StringUtils.isBlank(zipCode)) {
			return false;
		}
		return P_ZIP_CODE.matcher(zipCode).matches();
	}

	private final static Pattern P_NUMBER = Pattern.compile("[0-9]+(\\.[0-9]+)?");

	public static boolean isNumber(String number) {
		if (StringUtils.isBlank(number)) {
			return false;
		}
		if (P_NUMBER.matcher(number).matches()) {
			String prefix = number.split("\\.")[0];
			return prefix.length() <= 16;
		}
		return false;
	}

	private final static Pattern P_INT = Pattern.compile("^[1-9]\\d*$");

	public static boolean isInt(String number) {
		if (StringUtils.isBlank(number)) {
			return false;
		}
		if (P_INT.matcher(number).matches()) {
			double d = Double.valueOf(number);
			return d <= 2147483647d;
		}
		return false;
	}

	private final static Pattern P_INTEGER = Pattern.compile("^[-\\+]?[0-9]\\d*$");

	public static boolean isInteger(String number) {
		if (StringUtils.isBlank(number)) {
			return false;
		}
		if (P_INTEGER.matcher(number).matches()) {
			double d = Double.valueOf(number);
			return d <= 2147483647d;
		}
		return false;
	}

	private final static Pattern P_INDIADATE = Pattern.compile("^(?:[0-9]|[0][1-9]|[1-2]\\d|3[0-1])/(?:[1-9]|0[1-9]|[1][0-2])/(?:\\d{4})$");

	public static boolean isIndiaDate(String number) {
		if (StringUtils.isBlank(number)) {
			return false;
		}
		return P_INDIADATE.matcher(number).matches();
	}

	private final static Pattern P_DOUBLE2 = Pattern.compile("\\d{1,8}(\\.\\d{1,2})?");

	/**
	 * 验证数字小数点后是否超过2位
	 */
	public static boolean isTwoAfterPoint(String number) {
		if (StringUtils.isBlank(number)) {
			return false;
		}
		return P_DOUBLE2.matcher(number).matches();
	}

	private final static Pattern P_DOUBLE7 = Pattern.compile("\\d{1,10}(\\.\\d{1,7})?");

	/**
	 * 验证数字小数点后是否超过7位
	 */
	public static boolean isSeewenAfterPoint(String number) {
		if (StringUtils.isBlank(number)) {
			return false;
		}
		return P_DOUBLE7.matcher(number).matches();
	}

	private final static Pattern P_DATE_YM = Pattern.compile("([0-2])?[0-9]/(\\d{1,2})");

	/**
	 * 验证日期年月 mm/yy
	 */
	public static boolean isYearMonth(String number) {
		if (StringUtils.isBlank(number)) {
			return false;
		}
		return P_DATE_YM.matcher(number).matches();
	}

	//11位正整数
	private final static Pattern P_INLAND_NUM = Pattern.compile("^\\d{11}$");

	/**
	 * 国内或国外手机号验证
	 *
	 * @param areaCode 国家区号
	 * @param phoneNum 电话号码
	 * @return boolean
	 */
	public static boolean isPhone(String areaCode, String phoneNum) {
		if (StringUtils.isBlank(phoneNum)) {
			return false;
		}
		return P_INLAND_NUM.matcher(phoneNum).matches();
	}

	/**
	 * 验证字符长度  不能以空格开头
	 *
	 * @param str    字符串
	 * @param minLen 最小长度
	 * @param bigLen 最大长度
	 * @return boolean
	 */
	public static boolean isStrLen(String str, int minLen, int bigLen) {
		if (StringUtils.isBlank(str)) {
			return true;
		}
		StringBuilder reg = new StringBuilder();
		reg.append("^(?!\\s).{").append(minLen).append(",").append(bigLen).append("}$");
		return Pattern.compile(reg.toString()).matcher(str).matches();
	}

	private final static Pattern idCardNoPattern = Pattern.compile("^[0-9]*$");

	/**
	 * 验证身份证的合法性
	 *
	 * @param idCardNo
	 * @return
	 */
	public static boolean checkIdCardNo(String idCardNo) {
		try {
			if (StringUtils.isBlank(idCardNo) || idCardNo.trim().length() != 18) {
				return false;
			}
			//号码前17位
			String front_17 = idCardNo.substring(0, idCardNo.length() - 1);
			//校验位(最后一位)
			String verify = idCardNo.substring(17, 18);
			Matcher m = idCardNoPattern.matcher(front_17);
			if (!m.matches()) {
				return false;
			} else {
				return checkVerify(front_17, verify);
			}
		} catch (Exception e) {
			return false;
		}
	}

	/**
	 * 校验验证位合法性
	 *
	 * @param front_17
	 * @param verify
	 * @return
	 * @throws Exception
	 */
	public static boolean checkVerify(String front_17, String verify) throws Exception {
		try {
			int[] wi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
			String[] vi = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"};
			int s = 0;
			for (int i = 0; i < front_17.length(); i++) {
				int ai = Integer.parseInt(front_17.charAt(i) + "");
				s += wi[i] * ai;
			}
			int y = s % 11;
			String v = vi[y];
			if (!(verify.toUpperCase().equals(v))) {
				return false;
			}
			return true;
		} catch (Exception e) {
			throw e;
		}
	}

	//大小字母数字
	private final static Pattern P_CHARSTR_OR_NUMBER = Pattern.compile("^[A-Za-z0-9]+$");

	/**
	 * 验证大小字母数字
	 *
	 * @param str
	 * @return
	 */
	public static boolean checkCharStrOrNumber(String str) {
		if (StringUtils.isBlank(str)) {
			return false;
		}
		return P_CHARSTR_OR_NUMBER.matcher(str).matches();
	}

	/**
	 * 验证是否是男
	 *
	 * @param idCardNo 身份证
	 * @return 1: 男  0:女 -1：不合法
	 */
	public static int isMale(String idCardNo) {
		try {
			if (StringUtils.isBlank(idCardNo) || idCardNo.trim().length() != 18) {
				return -1;
			}
			String verify = idCardNo.substring(16, 17);
			if (StringUtils.isNumeric(verify)) {
				if (Integer.valueOf(verify) % 2 == 0) {
					return 0;
				}
				return 1;
			}
			return -1;
		} catch (Exception e) {
			return -1;
		}
	}

	/**
	 * 验证年龄是否属于某个年龄段
	 *
	 * @param ageRange 年龄段
	 * @param idCardNo 身份证
	 * @return true: 是 false:否
	 */
	public static boolean validateAge(String ageRange, String idCardNo) {
		String[] ageArr = ageRange.split("-");
		int age = Calendar.getInstance().get(Calendar.YEAR) - Integer.parseInt(idCardNo.substring(6, 10));
		if (age > Integer.parseInt(ageArr[1]) || age < Integer.parseInt(ageArr[0])) {
			return false;
		}
		return true;
	}

}
